package activity

import org.apache.poi.hssf.usermodel.*
import org.springframework.dao.DataIntegrityViolationException

class RegisterController {
    def exportService
    def grailsApplication//exportService會用到
    def emailService
    def historyService
    def regQtyService

    static allowedMethods = [save: "POST", update: "POST", delete: "POST"]
    
    def newEvents(Integer max) {
        def eventInstanceList = Event.findAllByDateStartGreaterThanEquals(new Date() - 1)
        params.max = Math.min(max ?: 200, 200)
        [eventInstanceList: eventInstanceList, eventInstanceTotal: eventInstanceList.size()]
    }
    
    def attendEvents(Integer max) {
        def eventInstanceList = Event.findAllByDateStartGreaterThanEquals(new Date() - 1)
        params.max = Math.min(max ?: 200, 200)
        [eventInstanceList: eventInstanceList, eventInstanceTotal: eventInstanceList.size()]
    }

    
    def oldEvents(Integer max) {
        def eventInstanceList = Event.findAllByDateStartLessThan(new Date())
        params.max = Math.min(max ?: 10, 100)
        render(view:"newEvents", model:[eventInstanceList: eventInstanceList,
                eventInstanceTotal: eventInstanceList.size()])
    }

    def index() {
        redirect(action: "newEvents", params: params)
    }

    def list(Long eventId, Integer max) {
        def event = Event.findById(eventId)
        def registerList = event ? Register.findAllByEvent(event) : []
        params.max = Math.min(max ?: 10, 100)
	if(params?.format && params.format != "html") {
            response.contentType = grailsApplication.config.grails.mime.types[params.format]
            response.setHeader("Content-disposition", "attachment; filename=output.${params.extension}")
            List fields = ['serial','event','sysCode','reader','CID','status',\
                'present','reader.gender','reader.tel1','reader.email1']
            Map labels = ['serial':'活動','event':'場次','sysCode':'系統碼',\
                'reader':'姓名','CID':'身分證號','status':'報名狀態','present':'出席狀態','reader.gender':'性別','reader.tel1':'電話','reader.email1':'Email'] 
            exportService.export(params.format, response.outputStream, registerList, fields, labels,[:], [:])
        }        
        [registerInstanceList: registerList, registerInstanceTotal: registerList.size()]
    }
    
    def attend(Long eventId, Integer max) {
        def event = Event.findById(eventId)
        def registerList = event ? Register.findAllByEventAndStatusInList(event, ["正取報名","候補補到","報名審過"]) : []
        params.max = Math.min(max ?: 10, 100)
        [registerInstanceList: registerList, registerInstanceTotal: registerList.size()]
    }
    
    
    def excelSerialReport(Long eventId) {
        def event = Event.findById(eventId)
        //輸出Excel
        if(params?.format && params.format != "html") {
            response.contentType = grailsApplication.config.grails.mime.types[params.format]
            response.setHeader("Content-disposition", "attachment; filename=output.${params.extension}")
            //寫入XLS
            def workbook = new HSSFWorkbook()//建立一個Excel活頁簿
            def sheet = workbook.createSheet("Sheet1")//在活頁簿中建立一個Sheet
            //第1列第1欄Row(0),Cell(0)
            int rowCount = 0
            def row = sheet.createRow(rowCount++)
            row.createCell(0).setCellValue(event.serial.name)
            row.createCell(1).setCellValue(event.name)
            row.createCell(2).setCellValue("簽到表")
            
            row = sheet.createRow(rowCount++)
            def eventList = Event.findAllWhere([serial: event.serial],[sort: "dateStart"])
            def i = 0
            row.createCell(i++).setCellValue("身分證字號")
            row.createCell(i++).setCellValue("姓名")
            row.createCell(i++).setCellValue("場數")
            row.createCell(i++).setCellValue("費用")//暫用，之後去除，ERROR
            row.createCell(i++).setCellValue(eventList[0].custom1)
            row.createCell(i++).setCellValue(eventList[0].custom2)
            int cellStart = i
            //列出場次日期
            //def eventList = Event.findAll("from Event as e where e.serial=:serial",
            //[serial: event.serial],[sort: "dateStart"])
            //def eventList = Event.findAll("from Event as e where e.serial=:serial order by e.dateStart",
            //[serial: event.serial])
            //println "eventList:"+eventList
            i = cellStart
            for (it in eventList) {
                row.createCell(i).setCellValue(""+formatDate(format:"MM/dd",date:it.dateStart))
                i++
                row.createCell(i).setCellValue("")
                i++
            }
            
            row = sheet.createRow(rowCount++)
            i = cellStart
            for (it in eventList) {
                row.createCell(i).setCellValue("上午")
                i++
                row.createCell(i).setCellValue("下午")
                i++
            }

            //找出報名資料
            //select R.CID, U.name, count(CID)                 
            def registerList = Register.executeQuery("select distinct R.CID as CID, R.reader.name as name \
                    from Register R where (R.status = '報名審過' or R.status = '正取報名' or R.status = '候補補到') \
                    and R.serial = ?",[event.serial])
            //println "registerList:"+registerList
            //def registerList = Register.listDistinct([serial: event.serial],[sort: "regTime"])
            //計算報名場數，驗證字
//            def multiRegs = Register.createCriteria().list() {
//                projections {
//                    groupProperty 'CID'
//                    countDistinct 'id', 'regNos'
//                }
//                eq "serial", event.serial
//                order ('regNos', 'desc')
//            }
//            println multiRegs

            for(it in registerList) {
                row = sheet.createRow(rowCount++)
                row.createCell(0).setCellValue(it[0])
                row.createCell(1).setCellValue(it[1])
                def priceMap = [1:1500,2:3000,3:4000,4:5000,5:6000]//暫用，之後去除，ERROR
                if (it[0]) {
                    def multiCount = Register.findAllWhere([CID: it[0]],[serial: event.serial])
                    row.createCell(2).setCellValue(multiCount.size())
                    row.createCell(3).setCellValue(priceMap.get(multiCount.size()))//暫用，之後去除，ERROR
                    row.createCell(4).setCellValue(multiCount[0].reader.custom1)
                    row.createCell(5).setCellValue(multiCount[0].reader.custom2)
                } else {
                    row.createCell(2).setCellValue(1)
                    row.createCell(3).setCellValue(1500)
                }
                //rowCount++
            }

            //輸出Excel
            def out = response.outputStream
            workbook.write(out)
            out.close()
        }
    }

    def create() {
        [registerInstance: new Register(params)]
    }

    def save() {
        def registerInstance = new Register(params)
        if (!registerInstance.save(flush: true)) {
            render(view: "create", model: [registerInstance: registerInstance])
            return
        }

        flash.message = message(code: 'default.created.message', args: [message(code: 'register.label', default: 'Register'), registerInstance.id])
        redirect(action: "show", id: registerInstance.id)
    }

    def show(Long id) {
        def registerInstance = Register.get(id)
        if (!registerInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'register.label', default: 'Register'), id])
            redirect(action: "list")
            return
        }
        [registerInstance: registerInstance]
    }

    def edit(Long id) {
        def registerInstance = Register.get(id)
        if (!registerInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'register.label', default: 'Register'), id])
            redirect(action: "list")
            return
        }

        [registerInstance: registerInstance]
    }

    def update(Long id, Long version) {
        def registerInstance = Register.get(id)
        if (!registerInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'register.label', default: 'Register'), id])
            redirect(action: "list")
            return
        }

        if (version != null) {
            if (registerInstance.version > version) {
                registerInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
                    [message(code: 'register.label', default: 'Register')] as Object[],
                          "Another user has updated this Register while you were editing")
                render(view: "edit", model: [registerInstance: registerInstance])
                return
            }
        }

        registerInstance.properties = params

        if (!registerInstance.save(flush: true)) {
            render(view: "edit", model: [registerInstance: registerInstance])
            return
        }

        regQtyService.calcRegisterQty(registerInstance.event.id)
        flash.message = message(code: 'default.updated.message', args: [message(code: 'register.label', default: 'Register'), registerInstance.id])
        redirect(action: "show", id: registerInstance.id)
    }

    def delete(Long id) {
        def registerInstance = Register.get(id)
        if (!registerInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'register.label', default: 'Register'), id])
            redirect(action: "list")
            return
        }
        try {
            def eventId = registerInstance.event.id
            registerInstance.delete(flush: true)
            regQtyService.calcRegisterQty(eventId)
            flash.message = message(code: 'default.deleted.message', args: [message(code: 'register.label', default: 'Register'), registerInstance.reader.name])
            redirect(action: "list", params: [eventId: eventId])
        }
        catch (DataIntegrityViolationException e) {
            flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'register.label', default: 'Register'), id])
            redirect(action: "show", id: id)
        }
    }
    
    def changeStandby(Long id) {
        def register = Register.get(id)
        if (!register) {
            redirect(action: "list", params: [eventId:register.event.id])
        }
        register.status = "候補補到"
        register.save()
        println "候補補到:"
        historyService.updateHistory(register, session)
        emailService.sendMail(register.status, register.event, register.reader, register)
        redirect(action: "list", params: [eventId:register.event.id])
    }
    
    def changeAudit(Long id) {
        def register = Register.get(id)
        if (!register) {
            redirect(action: "list", params: [eventId:register.event.id])
        }
        register.status = "報名審過"
        register.save()
        println "報名審過:"
        historyService.updateHistory(register, session)
        emailService.sendMail(register.status, register.event, register.reader, register)
        redirect(action: "list", params: [eventId:register.event.id])
    }

    def rejectAudit(Long id) {
        def register = Register.get(id)
        if (!register) {
            redirect(action: "list", params: [eventId:register.event.id])
        }
        register.status = "報名審拒"
        register.save()
        regQtyService.calcRegisterQty(register.event.id)
        println "報名審拒:"
        historyService.updateHistory(register, session)
        emailService.sendMail(register.status, register.event, register.reader, register)
        redirect(action: "list", params: [eventId:register.event.id])
    }
    
    def changePresent(Long id) {
        def register = Register.get(id)
        if (!register) {
            redirect(action: "list", params: [eventId:register.event.id])
        }
        register.present = "已出席"
        register.save()
        redirect(action: "list", params: [eventId:register.event.id])
    }

    def changeLeave(Long id) {
        def register = Register.get(id)
        if (!register) {
            redirect(action: "list", params: [eventId:register.event.id])
        }
        register.present = "已簽退"
        register.save()
        redirect(action: "list", params: [eventId:register.event.id])
    }

    def search() {
        def results = []
        if (!params.max) params.max = 200
        if (!params.field && !params.txt) {
            params.field = session.field
            params.txt = session.txt
        } else {
            session.field = params.field
            session.txt = params.txt
        }
        //確保為同場，在list加入,set參數
        //println "session.eventId:"+session.eventId
        if(params.txt.size() < 2) {
            flash.message = '查詢字元最少為兩個'
        } else if(params.field?.equals("系統碼")) {
            results = Register.findAllBySysCodeLike("%${params.txt}%")
        } else if (params.field?.equals("身分證號")) {
            def c = Register.createCriteria()
            results = c.listDistinct {
                if(session.eventId) {
                    and {
                        event {
                            eq ('id', new Long(session.eventId))
                        }
                    }
                }
                and {
                    reader {
                        like ('CID', "%${params.txt}%")
                    }
                }
            }
        } else if (params.field?.equals("姓名")) {
            def c = Register.createCriteria()
            results = c.listDistinct {
                if(session.eventId) {
                    and {
                        event {
                            eq ('id', new Long(session.eventId))
                        }
                    }
                }
                and {
                    reader {
                        like ('name', "%${params.txt}%")
                    }
                }
            }
        } else if(params.field?.equals("報名狀態")) {
            def c = Register.createCriteria()
            results = c.listDistinct {
                if(session.eventId) {
                    and {
                        event {
                            eq ('id', new Long(session.eventId))
                        }
                    }
                }
                and {
                    like ('status', "%${params.txt}%")
                }
            }
        } else if(params.field?.equals("出席狀態")) {
            def c = Register.createCriteria()
            results = c.listDistinct {
                if(session.eventId) {
                    and {
                        event {
                            eq ('id', new Long(session.eventId))
                        }
                    }
                }
                and {
                    like ('present', "%${params.txt}%")
                }
            }
        } else {
        }
        if (results?.size() > 0) {
            flash.message = null
        } else if (params.txt.size() < 2) {
            //前面已增加訊息，避免訊息被蓋掉
        } else if (params.field?.equals("報名狀態")) {
            flash.message = "報名狀態值：" + ["正取報名","候補報名","候補補到","待審報名","報名審過","報名審拒","自行取消"]
        } else if (params.field?.equals("出席狀態")) {            
            flash.message = "出席狀態值：" + ["未出席","已出席","已簽退"]
        } else {
            flash.message = '查無結果'
        }
        render(view:"list", model:[registerInstanceList: results, registerInstanceTotal: results?.size()])
    }
    
    def calcRegisterQty(Long eventId, String fromAction) {
        regQtyService.calcRegisterQty(eventId)
        if (fromAction) {
            redirect(action: fromAction)
        }
    }
}
